import 'dart:math';
import 'package:flutter/material.dart';

class ParticleBackground extends StatefulWidget {
  final Duration animationDuration;
  final int particleCount;
  final double maxParticleSize;
  final List<Color> gradientColors;

  const ParticleBackground({
    super.key,
    this.animationDuration = const Duration(seconds: 30),
    this.particleCount = 50,
    this.maxParticleSize = 3.0,
    this.gradientColors = const [
      Color.fromARGB(255, 37, 158, 245),
      Color.fromARGB(234, 0, 68, 136),
    ],
  });

  @override
  _ParticleBackgroundState createState() => _ParticleBackgroundState();
}

class _ParticleBackgroundState extends State<ParticleBackground>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late List<Particle> _particles;
  late Size _size;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(vsync: this, duration: widget.animationDuration);
    _controller.repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _size = MediaQuery.of(context).size;
    _particles = List.generate(
      widget.particleCount,
      (index) => Particle(
        position: Offset(
          Random().nextDouble() * _size.width,
          Random().nextDouble() * _size.height,
        ),
        velocity: Offset(
          (Random().nextDouble() - 0.5) * 0.5,
          (Random().nextDouble() - 0.5) * 0.5,
        ),
        size: Random().nextDouble() * widget.maxParticleSize,
        opacity: Random().nextDouble() * 0.5 + 0.2,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        _updateParticles();
        return Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
              colors: widget.gradientColors,
            ),
          ),
          child: CustomPaint(
            painter: ParticlePainter(_particles, _controller.value),
            child: Container(),
          ),
        );
      },
    );
  }

  void _updateParticles() {
    for (var particle in _particles) {
      particle.position += particle.velocity;

      // 边界检测
      if (particle.position.dx < 0 || particle.position.dx > _size.width) {
        particle.velocity = Offset(-particle.velocity.dx, particle.velocity.dy);
      }
      if (particle.position.dy < 0 || particle.position.dy > _size.height) {
        particle.velocity = Offset(particle.velocity.dx, -particle.velocity.dy);
      }
    }
  }
}

class Particle {
  Offset position;
  Offset velocity;
  double size;
  double opacity;

  Particle({
    required this.position,
    required this.velocity,
    required this.size,
    required this.opacity,
  });
}

class ParticlePainter extends CustomPainter {
  final List<Particle> particles;
  final double animationValue;

  ParticlePainter(this.particles, this.animationValue);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..style = PaintingStyle.fill
      ..color = Colors.white.withOpacity(0.5);

    for (var particle in particles) {
      // 随时间变化的透明度
      final alpha =
          (sin(animationValue * pi * 2 + particle.position.dx * 0.01) * 0.2 +
                  0.8) *
              particle.opacity;
      paint.color = Colors.white.withOpacity(alpha);

      canvas.drawCircle(particle.position, particle.size, paint);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
